package com.xhwl.centiotdata.handler.device.impl;

import com.alibaba.fastjson.JSONObject;
import com.xhwl.centiotdata.handler.device.DeviceIntegrationFactory;
import com.xhwl.centiotdata.handler.device.DeviceIntegrationHandler;
import com.xhwl.centiotdata.mq.producer.GeneralProducer;
import com.xhwl.centiotdata.pojo.dto.dahua.DeviceDaHuaDTO;
import com.xhwl.centiotdata.pojo.dto.device.DeviceIntegrationConfigDTO;
import com.xhwl.centiotdata.service.cent.IDeviceCentService;
import com.xhwl.centiotdata.suppliersystem.dahuaIcc.DeviceDaHuaIccHandler;
import com.xhwl.common.constant.cent.alarm.AlarmConstant;
import com.xhwl.common.dto.cent.device.DeviceDTO;
import com.xhwl.common.dto.cent.pedes.DeviceAttributeDTO;
import com.xhwl.common.enums.ProductEnum;
import com.xhwl.common.enums.device.DeviceOnlineStatusEnum;
import com.xhwl.common.pojo.cent.alarm.AlarmManagement;
import com.xhwl.common.pojo.cent.device.Device;
import com.xhwl.common.query.cent.device.DeviceQuery;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class DeviceIntegrationDaHuaIccHandler extends DeviceIntegrationHandler{
    private static final Logger log = LoggerFactory.getLogger(DeviceIntegrationDaHuaIccHandler.class);

    @Autowired
    private DeviceDaHuaIccHandler deviceDaHuaIccHandler;

    @Autowired
    private IDeviceCentService deviceCentService;

    @Autowired
    GeneralProducer generalProducer;
    @Override
    public void afterPropertiesSet() throws Exception {
        DeviceIntegrationFactory.register(ProductEnum.DAHUA_ICC.getId(), this);
    }

    @Override
    public void pullDevice(DeviceIntegrationConfigDTO configDTO) {
        if (configDTO.getDeviceType() == null) {
            log.error("projectId：{} pullDevice failed! deviceType is null!", configDTO.getProjectId());
            return;
        }
        // 拉取数据
        List<DeviceDaHuaDTO> deviceDaHuaDTOList = deviceDaHuaIccHandler.pullDevice(configDTO);
        if (CollectionUtils.isEmpty(deviceDaHuaDTOList)) {
            return;
        }
        // 转换数据
        List<DeviceDTO> deviceDTOList = this.handleDevice(configDTO, deviceDaHuaDTOList);
        // 存储业务中台
        deviceCentService.asyncUpdateDevice(deviceDTOList);
    }

    @Override
    public void pullAlarmHostDevice(DeviceIntegrationConfigDTO configDTO) {
        if (Objects.isNull(configDTO.getDeviceType())) {
            log.warn("获取的报警主机设备类型为空");
            return;
        }
        // 拉取设备信息
        List<DeviceDaHuaDTO> deviceDaHuaDTOList = deviceDaHuaIccHandler.pullAlarmHostDevice(configDTO);
        if (CollectionUtils.isEmpty(deviceDaHuaDTOList)) {
            log.warn("获取的报警主机设备信息为空");
            return;
        }
        // 同步设备信息
        List<DeviceDTO> deviceDTOList = this.handleDevice(configDTO, deviceDaHuaDTOList);
        log.info("同步的报警主机设备信息==>{}", deviceDTOList);
        deviceCentService.asyncUpdateDevice(deviceDTOList);
        // 同步设备在离线状态
        List<Device> deviceList = this.handleDeviceOnlineStatus(configDTO, deviceDaHuaDTOList);
        deviceCentService.asyncUpdateOnlineStatus(deviceList);
    }

    @Override
    public void pullDeviceOnlineStatus(DeviceIntegrationConfigDTO configDTO) {
        if (configDTO.getDeviceType() == null) {
            log.error("projectId：{} pullDeviceOnlineStatus failed! deviceType is null!", configDTO.getProjectId());
            return;
        }
        // 拉取数据
        List<DeviceDaHuaDTO> deviceDaHuaDTOList = deviceDaHuaIccHandler.pullDevice(configDTO);
        if (CollectionUtils.isEmpty(deviceDaHuaDTOList)) {
            return;
        }
        // 转换数据
        List<Device> deviceList = this.handleDeviceOnlineStatus(configDTO, deviceDaHuaDTOList);
        List<Device> offLineDevices = deviceList.stream().filter(s->s.getOnlineStatus().equals(DeviceOnlineStatusEnum.OFFLINE)).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(offLineDevices)) {
            DeviceQuery deviceQuery = new DeviceQuery();
            deviceQuery.setProjectId(configDTO.getProjectId());
            deviceQuery.setThirdDeviceIdList(offLineDevices.stream().map(Device::getThirdDeviceId).collect(Collectors.toList()));
            List<DeviceDTO> deviceDTOList = deviceCentService.listDevice(null, deviceQuery);
            offLineDevices.forEach(device->{
                AlarmManagement alarmManagement = new AlarmManagement();
                DeviceDTO deviceDTO = deviceDTOList.stream().filter(s-> StringUtils.equals( s.getThirdDeviceId(), device.getThirdDeviceId()))
                        .findAny().orElse(null);
                if(deviceDTO != null) {
                    //组装公共部分数据
                    alarmManagement.setProjectId(configDTO.getProjectId());
                    alarmManagement.setAlarmTime(new Date());
                    alarmManagement.setThirdDeviceId(device.getThirdDeviceId());
                    alarmManagement.setDeviceId(deviceDTO.getId());
                    //大华门禁离线告警
                    alarmManagement.setAlarmInventoryCode("17798944");
                    generalProducer.send(AlarmConstant.DAHUA_ICC_ALARM_TOPIC, alarmManagement);
                }
            });
        }
        // 存储业务中台
        deviceCentService.asyncUpdateOnlineStatus(deviceList);
    }

    private List<DeviceDTO> handleDevice(DeviceIntegrationConfigDTO configDTO, List<DeviceDaHuaDTO> deviceDaHuaDTOList) {
        return deviceDaHuaDTOList.stream().map(deviceDaHuaDTO -> {
            DeviceDTO deviceDTO = new DeviceDTO();
            deviceDTO.setProjectId(configDTO.getProjectId());
            deviceDTO.setProductId(configDTO.getProductId());
            deviceDTO.setCategoryId(configDTO.getCategoryEnum().getId());
            deviceDTO.setDeviceTypeId(configDTO.getDeviceType());
            deviceDTO.setName(deviceDaHuaDTO.getChannelName());
            deviceDTO.setThirdDeviceId(deviceDaHuaDTO.getChannelId());
            deviceDTO.setOnlineStatus(deviceDaHuaDTO.getIsDeviceOnline() ? DeviceOnlineStatusEnum.ONLINE.id : DeviceOnlineStatusEnum.OFFLINE.id);
            JSONObject attributeJson = null;
            if (configDTO.getDeviceType().intValue() == 1) {
                DeviceAttributeDTO deviceAttributeDTO = new DeviceAttributeDTO();
                deviceAttributeDTO.setIp(deviceDaHuaDTO.getDeviceIp());
                attributeJson = (JSONObject) JSONObject.toJSON(deviceAttributeDTO);
            }
            deviceDTO.setAttributeJson(attributeJson);
            return deviceDTO;
        }).collect(Collectors.toList());
    }

    private List<Device> handleDeviceOnlineStatus(DeviceIntegrationConfigDTO configDTO, List<DeviceDaHuaDTO> deviceDaHuaDTOList) {
        return deviceDaHuaDTOList.stream().map(deviceDaHuaDTO -> {
            Device device = new Device();
            device.setProjectId(configDTO.getProjectId());
            device.setThirdDeviceId(deviceDaHuaDTO.getChannelId());
            device.setDeviceTypeId(configDTO.getDeviceType());
            device.setOnlineStatus(deviceDaHuaDTO.getIsDeviceOnline() ? DeviceOnlineStatusEnum.ONLINE : DeviceOnlineStatusEnum.OFFLINE);
            return device;
        }).collect(Collectors.toList());
    }

}
